package com.qf.fronted.controller;


import com.qf.fronted.Utils.CommonUtils;
import com.qf.fronted.Utils.WXPayUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;

@Controller
@RequestMapping("/wxnotify")
public class WxpayNotifyController {

    /**
     * 微信支付回调
     * 这里在统一下单中提供的notify_url地址是:http://jincou.vipgz1.idcfengye.com/api/v1/order/callback
     * 该域名是sunny-ngrok中的二级域名，通过它映射到微信本地
     */
    @RequestMapping("callback")
    public void orderCallback(HttpServletRequest request, HttpServletResponse response) throws Exception {
        InputStream inputStream = request.getInputStream();
        //BufferedReader是包装设计模式，性能更搞
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        StringBuffer sb = new StringBuffer();
        //1、将微信回调信息转为字符串
        String line;
        while ((line = in.readLine()) != null) {
            sb.append(line);
        }
        in.close();
        inputStream.close();
        //2、将xml格式字符串格式转为map集合
        Map<String, String> callbackMap = WXPayUtil.xmlToMap(sb.toString());
        System.out.println(callbackMap.toString());
        //3、转为有序的map
        SortedMap<String, String> sortedMap = WXPayUtil.getSortedMap(callbackMap);
        //4、判断签名是否正确
        if (WXPayUtil.isCorrectSign(sortedMap, "sbNCm1JnevqI36LrEaxFwcaT0hkGxFnC")) {
            //5、判断回调信息是否成功
            if ("SUCCESS".equals(sortedMap.get("result_code"))) {
                //获取商户订单号
                //商户系统内部订单号，要求32个字符内，只能是数字、大小写字母_-|* 且在同一个商户号下唯一
                String outTradeNo = sortedMap.get("out_trade_no");
                System.out.println(outTradeNo);

                response.setContentType("text/xml");
                response.getWriter().println("success");
                return;
//                //6、数据库查找订单,如果存在则根据订单号更新该订单
//                VideoOrder dbVideoOrder = videoOrderService.findByOutTradeNo(outTradeNo);
//                System.out.println(dbVideoOrder);
//                if (dbVideoOrder != null && dbVideoOrder.getState() == 0) {  //判断逻辑看业务场景
//                    VideoOrder videoOrder = new VideoOrder();
//                    videoOrder.setOpenid(sortedMap.get("openid"));
//                    videoOrder.setOutTradeNo(outTradeNo);
//                    videoOrder.setNotifyTime(new Date());
//                    //修改支付状态，之前生成的订单支付状态是未支付，这里表面已经支付成功的订单
//                    videoOrder.setState(1);
//                    //根据商户订单号更新订单
//                    int rows = videoOrderService.updateVideoOderByOutTradeNo(videoOrder);
//                    System.out.println(rows);
//                    //7、通知微信订单处理成功
//                    if (rows == 0) {
//                        response.setContentType("text/xml");
//                        response.getWriter().println("success");
//                        return;
//                    }
//                }
            }
        }
        response.setContentType("text/xml");
        response.getWriter().println("fail");

    }
    /**
     * 校验签名
     */
    public static boolean isCorrectSign(SortedMap<String, String> params, String key){

        //1、再进行一次生成sign
        String sign = createSign(params,key);
        String weixinPaySign = params.get("sign").toUpperCase();
        //将两次生成的sign比较看是否一致
        return weixinPaySign.equals(sign);
    }

    /**
     * 生成微信支付sign
     */
    public static String createSign(SortedMap<String, String> params, String key){
        StringBuilder sb = new StringBuilder();
        Set<Map.Entry<String, String>> es =  params.entrySet();
        Iterator<Map.Entry<String,String>> it =  es.iterator();
        //生成 stringA="appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA";
        while (it.hasNext()){
            Map.Entry<String,String> entry = (Map.Entry<String,String>)it.next();
            String k = (String)entry.getKey();
            String v = (String)entry.getValue();
            if(null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)){
                sb.append(k+"="+v+"&");
            }
        }
        sb.append("key=").append(key);
        String sign = CommonUtils.MD5(sb.toString()).toUpperCase();
        return sign;
    }
}
